package com.ww.juc.futureandcallable;

import java.util.concurrent.*;

public class AsyncFutureExample2 {

    // 自定义线程池
    private final static int AVALIABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();

    private final static ThreadPoolExecutor POOL_EXECUTOR = new ThreadPoolExecutor(AVALIABLE_PROCESSORS,
            AVALIABLE_PROCESSORS * 2,
            1,
            TimeUnit.MINUTES,
            new LinkedBlockingQueue<>(5),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public static String doSomethingA() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("----------doSomethingA---------");
        return "TaskAResult";
    }

    public static String doSomethingB() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("----------doSomethingB---------");
        return "TaskBResult";
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException, ExecutionException {
//        test01();
        test02();
    }

    private static void test02() throws ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();

        // 1 开启异步单元执行任务A
        Future<String> futureTask = POOL_EXECUTOR.submit(() -> {
            String result = null;
            try {
                result = doSomethingA();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        });

        // 2 执行任务B
        String taskBResult = doSomethingB();

        // 3 同步等待线程A运行结束
        String taskResult = futureTask.get();

        // 4. 打印两个任务执行结果
        System.out.println(taskResult + " " + taskBResult);
        System.out.println(System.currentTimeMillis() - start);
    }

    private static void test01() throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillis();

        // 1 创建Future任务
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            String result = null;
            try {
                result = doSomethingA();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        });

        // 2 开启异步单元执行任务A
        POOL_EXECUTOR.execute(futureTask);

        // 3 执行任务B
        String taskBResult = doSomethingB();

        // 4 同步等待线程A运行结束
        String taskAResult = futureTask.get();

        System.out.println(taskAResult + " " + taskBResult);
        System.out.println(System.currentTimeMillis() - start);

        POOL_EXECUTOR.shutdown();
    }
}
